3.x "recreation"
*/
-#include <cassert> // for assert
-#include <cmath> // for cos, sqrt
-#include <cstdio> // for printf, SEEK_CUR, SEEK_SET
-#include <cstdint>
-#include <cstring> // for strncmp, strlen, memset
-#include <vector> // for vector
-
-#include <QByteArray> // for QByteArray
-#include <QChar> // for operator==, QChar
-#include <QScopedArrayPointer> // for QScopedArrayPointer
-#include <QString> // for QString
-#include <QtGlobal> // for qPrintable, Q_UNUSED
+#include <cmath> // for abs
+#include <cstdint> // for uint8_t
+#include <cstdio> // for printf, SEEK_CUR, SEEK_SET
+#include <cstring> // for strlen, strncmp
+#include <vector> // for vector
+
+#include <QByteArray> // for QByteArray
+#include <QScopedArrayPointer> // for QScopedArrayPointer
+#include <QString> // for QString
+#include <QStringLiteral> // for qMakeStringPrivate, QStringLiteral
+#include <QVector> // for QVector
+#include <QtGlobal> // for qPrintable, Q_UNUSED
#include "defs.h"
-#include "gbfile.h" // for gbfread, gbfgetc, gbfgetint32, gbfwrite, gbfputint16, gbfseek, gbfgetdbl, gbfgetint16, gbfputdbl, gbfclose, gbfputint32, gbfile, gbfopen_le, gbfgetuint16
-#include "jeeps/gpsmath.h" // for GPS_Math_WGS84LatLonH_To_XYZ, GPS_Math_WGS84_To_Known_Datum_M, GPS_Math_Deg_To_Rad, GPS_Math_Known_Datum_To_WGS84_M
+#include "gbfile.h" // for gbfread, gbfgetc, gbfgetint32, gbfreadbuf, gbfseek, gbfgetdbl, gbfgetint16, gbfclose, gbfgetnativecstr, gbfgetuint16, gbfopen_le, gbfile
+#include "jeeps/gpsmath.h" // for GPS_Math_Known_Datum_To_WGS84_M
#define MYNAME "TPO"
static char* dumpheader = nullptr;
-#ifdef ENABLE_TPO_WRITE
-static char* output_state = nullptr;
-#endif
-#ifdef ENABLE_TPO_WRITE
-static
-QVector<arglist_t> tpo2_args = {
- {
- "dumpheader", &dumpheader, "Display the file header bytes",
- "0", ARGTYPE_BOOL, ARG_NOMINMAX
- },
- {
- "state", &output_state, "State map format to write, default=CA",
- "CA", ARGTYPE_STRING, ARG_NOMINMAX
- },
-};
-#else
-//
-// Note that we've disabled the write capabilities for the tpo2
-// format at present. The "testo" tests were failing on some
-// platforms and there wasn't anyone willing to work on the problem.
-// If this is fixed in the future we can go back to the tpo2_args[]
-// above.
-//
static
QVector<arglist_t> tpo2_args = {
};
-#endif
static
QVector<arglist_t> tpo3_args = {
static gbfile* tpo_file_in;
static double track_length;
-#ifdef ENABLE_TPO_WRITE
-static gbfile* tpo_file_out;
-
-static double output_track_lon_scale;
-static double output_track_lat_scale;
-
-static unsigned int track_out_count;
-static double first_track_waypoint_lat;
-static double first_track_waypoint_lon;
-static double last_waypoint_x;
-static double last_waypoint_y;
-static double last_waypoint_z;
-#endif
-
/*******************************************************************************/
/* READ */
/*******************************************************************************/
}
}
-
-
-
-#ifdef ENABLE_TPO_WRITE
-/*******************************************************************************/
-/* WRITE */
-/*******************************************************************************/
-
-/* tpo_write_file_header()
- Write the appropriate header for the desired TOPO! state.
-
- National Geographic sells about 75 different state and regional software
- programs called TOPO! that use the TPO format. Each one uses a different
- header data sequence. The header contains the name of the state maps, as well
- as some map scaling information and other data. In most cases, you can't open
- a TPO file created by a different state/regional version of TOPO! than the one
- you're using yourself. When writing a TPO file, it is therefore necessary to
- specify what TOPO! state product to create the file for. I believe that the
- TOPO! regional products can open TPO files created by the TOPO! state products
- as long as the track data is within the area covered by the regional product.
- As a result, it's only necessary to decide what state product output format to
- use.
-
- TO ADD SUPPORT FOR ANOTHER STATE:
- 1. Obtain an example .tpo file generated by the state product for which you wish
- to add support. National Geographic MapXchange (http://maps.nationalgeographic.com/topo/search.cfm)
- is a good source of .tpo files.
- 2. Run gpsbabel using the "dumpheader" option of the TPO format converter, and
- specifying a dummy output file. For example:
- gpsbabel -t -i tpo,dumpheader=1 -f sample_file.tpo -o csv -F dummy.txt
- This will write a snippet of C code containing the header bytes to the shell window.
- 3. Add a new if() clause to tpo_write_file_header(). Copy the header bytes definition
- from the previous step.
- 4. Recompile gpsbabel.
- 5. You should now be able write TPO output in the new state's format. For example, if
- you added support for Texas:
- gpsbabel -t -i gpx -f input.gpx -o tpo,state="TX" -F output.tpo */
-static void
-tpo_write_file_header()
-{
- assert(output_state != nullptr);
-
- /* force upper-case state name */
- strupper(output_state);
-
- if (strncmp("CA", output_state, 2) == 0) {
-
- unsigned char header_bytes[] = {
- 0x18, 0x43, 0x61, 0x6C, 0x69, 0x66, 0x6F, 0x72,
- 0x6E, 0x69, 0x61, 0x20, 0x53, 0x68, 0x61, 0x64,
- 0x65, 0x64, 0x20, 0x52, 0x65, 0x6C, 0x69, 0x65,
- 0x66, 0x03, 0x43, 0x41, 0x31, 0x05, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x80, 0x5C, 0x40, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x27, 0x43, 0x3A, 0x5C,
- 0x50, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20,
- 0x46, 0x69, 0x6C, 0x65, 0x73, 0x5C, 0x54, 0x4F,
- 0x50, 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F,
- 0x44, 0x41, 0x54, 0x41, 0x5C, 0x43, 0x41, 0x5F,
- 0x44, 0x30, 0x31, 0x5C, 0x20, 0x43, 0x3A, 0x5C,
- 0x50, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20,
- 0x46, 0x69, 0x6C, 0x65, 0x73, 0x5C, 0x54, 0x4F,
- 0x50, 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F,
- 0x44, 0x41, 0x54, 0x41, 0x5C, 0x12, 0x43, 0x3A,
- 0x5C, 0x54, 0x4F, 0x50, 0x4F, 0x21, 0x5C, 0x54,
- 0x50, 0x4F, 0x5F, 0x44, 0x41, 0x54, 0x41, 0x5C,
- 0x00, 0x00, 0x00, 0xDC, 0x30, 0x32, 0x30, 0x32,
- 0x30, 0x32, 0x30, 0x33, 0x30, 0x33, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32,
- 0x30, 0x33, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x34, 0x30, 0x34, 0x30, 0x34, 0x30, 0x34,
- 0x30, 0x36, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x35, 0x30, 0x35, 0x30, 0x34, 0x30, 0x36,
- 0x30, 0x36, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35,
- 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37,
- 0x30, 0x37, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35,
- 0x30, 0x35, 0x30, 0x37, 0x30, 0x37, 0x30, 0x37,
- 0x30, 0x38, 0x30, 0x38, 0x30, 0x39, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35,
- 0x31, 0x30, 0x30, 0x38, 0x30, 0x38, 0x30, 0x38,
- 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30,
- 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31,
- 0x30, 0x39, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
- 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x30, 0x39, 0x30, 0x39,
- 0x0D, 0x55, 0x6E, 0x69, 0x74, 0x65, 0x64, 0x20,
- 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40, 0xBC, 0x23,
- 0x63, 0xB5, 0xF9, 0x3A, 0x50, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x50, 0x40, 0x22, 0xE2,
- 0xE6, 0x54, 0x32, 0x28, 0x22, 0x40, 0x0A, 0x43,
- 0x61, 0x6C, 0x69, 0x66, 0x6F, 0x72, 0x6E, 0x69,
- 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F,
- 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5C,
- 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x40, 0x16, 0x2A, 0x47, 0x65, 0x6E, 0x65, 0x72,
- 0x61, 0x6C, 0x20, 0x52, 0x65, 0x66, 0x65, 0x72,
- 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4D, 0x61, 0x70,
- 0x00, 0x09, 0x3D, 0x00, 0x0C, 0x43, 0x41, 0x31,
- 0x5F, 0x4D, 0x41, 0x50, 0x31, 0x5C, 0x53, 0x31,
- 0x4C, 0xAF, 0x02, 0x15, 0x03, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x26, 0x40, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x24, 0x40, 0x84, 0x00, 0x78,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x16,
- 0x2A, 0x4E, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x61,
- 0x6C, 0x20, 0x41, 0x74, 0x6C, 0x61, 0x73, 0x20,
- 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0xE8, 0x32,
- 0x0D, 0x00, 0x02, 0x44, 0x41, 0x23, 0x01, 0x6C,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
- 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
- 0x3F, 0x3C, 0x00, 0x3C, 0x00, 0x01, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x10, 0x2A, 0x35, 0x30, 0x30,
- 0x4B, 0x20, 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65,
- 0x72, 0x69, 0x65, 0x73, 0xC0, 0xFE, 0x04, 0x00,
- 0x02, 0x44, 0x46, 0x00, 0x01, 0x40, 0x01, 0xB5,
- 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0xB5,
- 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0x28,
- 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x10, 0x2A, 0x31, 0x30, 0x30, 0x4B, 0x20,
- 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, 0x72, 0x69,
- 0x65, 0x73, 0x50, 0xC3, 0x00, 0x00, 0x02, 0x44,
- 0x4B, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x2D, 0x00, 0x2D,
- 0x00, 0x0C, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x10,
- 0x2A, 0x37, 0x2E, 0x35, 0x27, 0x20, 0x4D, 0x61,
- 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73,
- 0x0F, 0x3C, 0x00, 0x00, 0x02, 0x44, 0x51, 0x00,
- 0x00, 0x00, 0x01, 0x9A, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x3F, 0x9A, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x89, 0x3F, 0x5A, 0x00, 0x2D, 0x00, 0x0D,
- 0x00, 0x01, 0x00, 0x28, 0x00
- };
-
- gbfwrite(header_bytes, sizeof(header_bytes), 1, tpo_file_out);
- } else if (strncmp("CT", output_state, 2) == 0 ||
- strncmp("MA", output_state, 2) == 0 ||
- strncmp("ME", output_state, 2) == 0 ||
- strncmp("NJ", output_state, 2) == 0 ||
- strncmp("NH", output_state, 2) == 0 ||
- strncmp("NY", output_state, 2) == 0 ||
- strncmp("RI", output_state, 2) == 0 ||
- strncmp("VT", output_state, 2) == 0) {
- /* These 8 states are all covered in a single "Northeast" title */
-
- unsigned char header_bytes[] = {
- 0x1E, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x65, 0x61,
- 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x55, 0x53,
- 0x41, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x64,
- 0x20, 0x52, 0x65, 0x6C, 0x69, 0x65, 0x66, 0x03,
- 0x4E, 0x45, 0x31, 0x05, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0x40, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0x40, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x50, 0x40, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x40, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0B, 0x44, 0x3A, 0x5C, 0x4E, 0x45,
- 0x31, 0x5F, 0x44, 0x30, 0x31, 0x5C, 0x12, 0x43,
- 0x3A, 0x5C, 0x54, 0x4F, 0x50, 0x4F, 0x21, 0x5C,
- 0x54, 0x50, 0x4F, 0x5F, 0x44, 0x41, 0x54, 0x41,
- 0x5C, 0x12, 0x45, 0x3A, 0x5C, 0x54, 0x4F, 0x50,
- 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F, 0x44,
- 0x41, 0x54, 0x41, 0x5C, 0x00, 0x00, 0x00, 0xFF,
- 0x18, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x37,
- 0x30, 0x37, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x37, 0x30, 0x37, 0x30, 0x37, 0x30, 0x37,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, 0x34,
- 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37,
- 0x30, 0x37, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x30, 0x33,
- 0x30, 0x34, 0x30, 0x34, 0x30, 0x35, 0x30, 0x35,
- 0x30, 0x36, 0x30, 0x36, 0x30, 0x36, 0x30, 0x36,
- 0x30, 0x36, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32,
- 0x30, 0x33, 0x30, 0x33, 0x30, 0x34, 0x30, 0x34,
- 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x36,
- 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32,
- 0x30, 0x32, 0x30, 0x32, 0x30, 0x33, 0x30, 0x33,
- 0x30, 0x38, 0x30, 0x38, 0x30, 0x38, 0x30, 0x39,
- 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32,
- 0x30, 0x33, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38,
- 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, 0x30, 0x39,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30,
- 0x31, 0x30, 0x31, 0x30, 0x30, 0x39, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x0D, 0x55, 0x6E, 0x69, 0x74, 0x65,
- 0x64, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x4E, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x50, 0x40,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x40,
- 0x10, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x65, 0x61,
- 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x55, 0x53,
- 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54,
- 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x48,
- 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x50,
- 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42,
- 0x40, 0x16, 0x2A, 0x47, 0x65, 0x6E, 0x65, 0x72,
- 0x61, 0x6C, 0x20, 0x52, 0x65, 0x66, 0x65, 0x72,
- 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4D, 0x61, 0x70,
- 0x00, 0x09, 0x3D, 0x00, 0x0C, 0x4E, 0x45, 0x31,
- 0x5F, 0x4D, 0x41, 0x50, 0x31, 0x5C, 0x53, 0x31,
- 0x4C, 0x68, 0x03, 0x16, 0x03, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2C, 0x40, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x24, 0x40, 0x8C, 0x00, 0x64,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x16,
- 0x2A, 0x4E, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x61,
- 0x6C, 0x20, 0x41, 0x74, 0x6C, 0x61, 0x73, 0x20,
- 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0xE8, 0x32,
- 0x0D, 0x00, 0x02, 0x44, 0x41, 0x0B, 0x01, 0x6C,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
- 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
- 0x3F, 0x3C, 0x00, 0x3C, 0x00, 0x01, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x10, 0x2A, 0x35, 0x30, 0x30,
- 0x4B, 0x20, 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65,
- 0x72, 0x69, 0x65, 0x73, 0xC0, 0xFE, 0x04, 0x00,
- 0x02, 0x44, 0x46, 0xEA, 0x00, 0x40, 0x01, 0xB5,
- 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0xB5,
- 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0x28,
- 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x10, 0x2A, 0x31, 0x30, 0x30, 0x4B, 0x20,
- 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, 0x72, 0x69,
- 0x65, 0x73, 0x50, 0xC3, 0x00, 0x00, 0x02, 0x44,
- 0x4B, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x2D, 0x00, 0x2D,
- 0x00, 0x0C, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x10,
- 0x2A, 0x37, 0x2E, 0x35, 0x27, 0x20, 0x4D, 0x61,
- 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73,
- 0x0F, 0x3C, 0x00, 0x00, 0x02, 0x44, 0x51, 0x00,
- 0x00, 0x00, 0x01, 0x9A, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x3F, 0x9A, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x89, 0x3F, 0x5A, 0x00, 0x2D, 0x00, 0x0D,
- 0x00, 0x01, 0x00, 0x28, 0x00
- };
-
- gbfwrite(header_bytes, sizeof(header_bytes), 1, tpo_file_out);
- }
-
- else {
- fatal(MYNAME ": writing output for state \"%s\" is not currently supported.\n", output_state);
- }
-}
-
-static void
-tpo_track_hdr(const route_head* rte)
-{
- double amt;
- unsigned char temp_buffer[8];
- unsigned char visibility_flags[] = { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00 };
- unsigned char unknown1[] = { 0xFF, 0x00, 0x00, 0x00 };
- unsigned char bounding_box[8] = { 0x00, 0x80, 0x00, 0x80, 0xFF, 0x7F, 0xFF, 0x7F };
-
- Waypoint* first_track_waypoint = rte->waypoint_list.front();
-
- /* zoom level 1-5 visibility flags */
- gbfwrite(visibility_flags, 1, sizeof(visibility_flags), tpo_file_out);
-
- /* 8 bytes of zeros, meaning unknown */
- memset(temp_buffer, 0, sizeof(temp_buffer));
- gbfwrite(temp_buffer, 1, sizeof(temp_buffer), tpo_file_out);
-
- /* 4 more unknown bytes, possibly sign flags for the longitude and latitude? */
- gbfwrite(unknown1, 1, sizeof(unknown1), tpo_file_out);
-
- /* the starting point of the route */
- /* convert lat/long to NAD27/CONUS datum */
- GPS_Math_WGS84_To_Known_Datum_M(
- first_track_waypoint->latitude,
- first_track_waypoint->longitude,
- first_track_waypoint->altitude,
- &first_track_waypoint_lat,
- &first_track_waypoint_lon,
- &amt,
- 78);
-
- /* swap the sign back *after* the datum conversion */
- first_track_waypoint_lon *= -1.0;
-
- /* Compute this track's scaling factors: Used for scaling each track point and then
- later written out to the track footer. These are approximately the ratios between
- pixels and degrees when viewing the 1:24000 map in TOPO!. In practice, it doesn't
- appear to be necessary that they be correct, as long as the same values are used
- for doing the scaling and for writing into the track footer data. */
- output_track_lat_scale = 4.8828125e-005; /* TOPO! appears to use a constant lat scale */
- output_track_lon_scale = output_track_lat_scale / cos(GPS_Math_Deg_To_Rad(first_track_waypoint_lat));
-
- /* 8 bytes - longitude */
- gbfputdbl(first_track_waypoint_lon, tpo_file_out);
-
- /* 8 bytes - latitude */
- gbfputdbl(first_track_waypoint_lat, tpo_file_out);
-
- /* 8 bytes: seems to be bounding box info */
- gbfwrite(bounding_box, 1, sizeof(bounding_box), tpo_file_out);
-
- /* number of route points */
- gbfputint16(rte->rte_waypt_ct(), tpo_file_out);
-
- /* initialize the track length computation */
- track_length = 0;
- GPS_Math_WGS84LatLonH_To_XYZ(
- first_track_waypoint->latitude,
- first_track_waypoint->longitude,
- 0.0,
- &last_waypoint_x,
- &last_waypoint_y,
- &last_waypoint_z);
-}
-
-static void
-tpo_track_disp(const Waypoint* waypointp)
-{
- double lat, lon, amt, x, y, z;
-
- /* fprintf(stderr, "%f/%f\n", waypointp->latitude, waypointp->longitude); */
-
- /* convert lat/lon position to XYZ meters */
- GPS_Math_WGS84LatLonH_To_XYZ(
- waypointp->latitude,
- waypointp->longitude,
- 0.0,
- &x,
- &y,
- &z);
-
- /* increase the track length by the 3D length of last track segment in feet */
- track_length += METERS_TO_FEET(sqrt(
- (x - last_waypoint_x) * (x - last_waypoint_x) +
- (y - last_waypoint_y) * (y - last_waypoint_y) +
- (z - last_waypoint_z) * (z - last_waypoint_z)));
- last_waypoint_x = x;
- last_waypoint_y = y;
- last_waypoint_z = z;
-
- /* convert lat/long to NAD27/CONUS datum */
- GPS_Math_WGS84_To_Known_Datum_M(
- waypointp->latitude,
- waypointp->longitude,
- waypointp->altitude,
- &lat,
- &lon,
- &amt,
- 78);
-
- /* swap the sign back *after* the datum conversion */
- lon *= -1.0;
-
- /* longitude delta from first route point */
- short lon_delta = (short)((first_track_waypoint_lon - lon) / output_track_lon_scale);
- gbfputint16(lon_delta, tpo_file_out);
-
- /* latitude delta from first route point */
- short lat_delta = (short)((first_track_waypoint_lat - lat) / output_track_lat_scale);
- gbfputint16(lat_delta, tpo_file_out);
-
- /*
- fprintf(stderr, "%f %f: %x %x - %f %f %f / %f\n", lon, lat, lon_delta, lat_delta, first_track_waypoint_lat, lat, output_track_lat_scale, (first_track_waypoint_lat - lat) );
- */
-
-}
-
-static void
-tpo_track_tlr(const route_head*)
-{
- static const unsigned char unknown1[] = { 0x06, 0x00 };
-
- static const unsigned char continue_marker[] = { 0x01, 0x80 };
- static const unsigned char end_marker[] = { 0x00, 0x00 };
-
- /* pixel to degree scaling factors */
- gbfputdbl(output_track_lon_scale, tpo_file_out);
- gbfputdbl(output_track_lat_scale, tpo_file_out);
-
- /* 4 bytes: the total length of the route */
- gbfputint32(track_length, tpo_file_out);
-
- /* 2 unknown bytes */
- gbfwrite(unknown1, 1, sizeof(unknown1), tpo_file_out);
-
- /* the last track ends with 0x0000 instead of 0x0180 */
- track_out_count++;
- if (track_out_count == track_count()) {
- gbfwrite(end_marker, 1, sizeof(end_marker), tpo_file_out);
- } else {
- gbfwrite(continue_marker, 1, sizeof(continue_marker), tpo_file_out);
- }
-}
-
-static void
-tpo_wr_init(const QString& fname)
-{
- if (doing_wpts || doing_rtes) {
- fatal(MYNAME ": this file format only supports tracks, not waypoints or routes.\n");
- }
-
- tpo_file_out = gbfopen_le(fname, "wb", MYNAME);
- tpo_write_file_header();
-}
-
-static void
-tpo_wr_deinit()
-{
- /* the file footer is six bytes of zeroes */
- unsigned char file_footer_bytes[6];
- memset(file_footer_bytes, 0, sizeof(file_footer_bytes));
- gbfwrite(file_footer_bytes, 1, sizeof(file_footer_bytes), tpo_file_out);
-
- gbfclose(tpo_file_out);
-}
-
-static void
-tpo_write()
-{
- unsigned char unknown1[] = { 0xFF, 0xFF, 0x01, 0x00 };
-
- const char* chunk_name = "CTopoRoute";
- int chunk_name_length = strlen(chunk_name);
-
- /* write the total number of tracks */
- gbfputint16(track_count(), tpo_file_out);
-
- /* 4 unknown bytes */
- gbfwrite(unknown1, 1, 4, tpo_file_out);
-
- /* chunk name: "CTopoRoute" */
- gbfputint16(chunk_name_length, tpo_file_out);
- gbfwrite(chunk_name, 1, chunk_name_length, tpo_file_out);
-
- track_out_count = 0;
- track_disp_all(tpo_track_hdr, tpo_track_tlr, tpo_track_disp);
-}
-#endif // ENABLE_TPO_WRITE
-
/* TPO 2.x format can read tracks only */
ff_vecs_t tpo2_vecs = {
ff_type_file, /* ff_type_internal */
-#ifdef ENABLE_TPO_WRITE
- { ff_cap_none, (ff_cap)(ff_cap_read | ff_cap_write), ff_cap_none },
-#else
{ ff_cap_none, ff_cap_read, ff_cap_none },
-#endif
tpo_rd_init,
-#ifdef ENABLE_TPO_WRITE
- tpo_wr_init,
-#else
nullptr,
-#endif
tpo_rd_deinit,
-#ifdef ENABLE_TPO_WRITE
- tpo_wr_deinit,
-#else
nullptr,
-#endif
tpo_read,
-#ifdef ENABLE_TPO_WRITE
- tpo_write,
-#else
nullptr,
-#endif
nullptr,
&tpo2_args,
NULL_POS_OPS